package utils

import (
	"time"

	"gitee.com/sansaniot/ssiot-core/logger"
	"github.com/guonaihong/gout"
)

//定义一个全局的
var globalWithOpt = &gout.Client{}

var goutDebug = true

//定义一个初始化的方法
func InitHttpEvent() {
	//定义相关全局配置
	opt := []gout.Option{gout.WithInsecureSkipVerify(), gout.WithClose3xxJump(), gout.WithTimeout(time.Second * 30)}
	//初始化请求对象
	globalWithOpt = gout.NewWithOpt(opt...)
	//初始化
	logger.Info("初始化全局http对象完成")
}

type HttpResponse struct {
	Status int                    `json:"status"`
	Msg    string                 `json:"message"`
	Data   map[string]interface{} `json:"data"`
	Result map[string]interface{} `json:"result"`
}

type HttpResponse2 struct {
	Status int                    `json:"status"`
	Msg    string                 `json:"message"`
	Data   string                 `json:"data"`
	Result map[string]interface{} `json:"result"`
}

//get请求无参数处理
func GetHttp(url string) HttpResponse {
	//无请求参数调用
	return GetHttpBase(url, make(map[string]interface{}), formatHttpHeader())
}

//get请求无参数处理
func GetHttpWithParam(url string, jsonQuery map[string]interface{}) HttpResponse {
	//无请求参数调用
	return GetHttpBase(url, jsonQuery, formatHttpHeader())
}

//get请求无参数处理
func GetHttpWithParamAndHeader(url string, jsonQuery map[string]interface{}, header map[string]interface{}) HttpResponse {
	//无请求参数调用
	return GetHttpBase(url, jsonQuery, header)
}

//post请求无参数处理
func PostHttp(url string) HttpResponse {
	//无请求参数调用
	return PostHttpBase(url, make(map[string]interface{}), formatHttpHeader())
}

//get请求无参数处理
func PostHttpWithJson(url string, jsonBody map[string]interface{}, header map[string]interface{}) HttpResponse {
	//无请求参数调用
	return PostHttpBase(url, jsonBody, formatHttpHeader())
}

//get请求无参数处理
func PostHttpWithJsonAndHeader(url string, jsonBody map[string]interface{}, header map[string]interface{}) HttpResponse {
	//无请求参数调用
	return PostHttpBase(url, jsonBody, header)
}
func PostHttpWithJsonAndHeader2(url string, jsonBody map[string]interface{}, header map[string]interface{}) HttpResponse2 {
	//无请求参数调用
	return PostHttpBase2(url, jsonBody, header)
}

//map参数
func GetHttpBase(url string, jsonQuery map[string]interface{}, header map[string]interface{}) HttpResponse {
	//请求响应的结构体
	responseStr, responseBody := "", HttpResponse{}
	code := 0
	//请求发送逻辑
	err := gout.
		//GET请求
		GET(url).
		//设置debug模式
		Debug(checkDebug()).
		// 设置http header
		SetHeader(gout.H(header)).
		//设置请求http header
		SetQuery(gout.H(jsonQuery)).
		//设置不同的code类型的回调处理
		Callback(func(c *gout.Context) (err error) {
			switch c.Code {
			case 200: //http code为200时，服务端返回的是json 结构
				c.BindJSON(&responseBody)
			default: //http code不为200时，服务端返回是html 字符串
				c.BindBody(&responseStr)
			}
			code = c.Code
			return nil
		}).
		// 结束函数
		Do()
	// 判断错误
	if err != nil {
		//打印错误
		logger.Errorf("请求异常 url=[%v] err=[%v]", url, err)
	}
	//错误响应格式处理
	if code != 200 {
		//缓存错误信息
		responseBody.Status = code
		responseBody.Msg = responseStr
	}
	//打印请求参数
	logger.Debugf("接口请求结果 url=[%v] response=[%+v]", url, responseBody)
	//返回响应
	return responseBody
}

func PostHttpBase(url string, jsonBody map[string]interface{}, header map[string]interface{}) HttpResponse {
	//请求响应的结构体
	responseStr, responseBody := "", HttpResponse{}
	code := 0
	//请求发送逻辑
	err := gout.
		// POST请求
		POST(url).
		// 打开debug模式
		Debug(checkDebug()).
		// 设置http header
		SetHeader(gout.H(header)).
		// SetJSON设置http body为json
		// 同类函数有SetBody, SetYAML, SetXML, SetForm, SetWWWForm
		SetJSON(gout.H(jsonBody)).
		//设置不同的code类型的回调处理
		Callback(func(c *gout.Context) (err error) {
			switch c.Code {
			case 200: //http code为200时，服务端返回的是json 结构
				c.BindJSON(&responseBody)
			default: //http code不为200时，服务端返回是html 字符串
				c.BindBody(&responseStr)
			}
			code = c.Code
			return nil
		}).
		// 结束函数
		Do()
	// 判断错误
	if err != nil {
		//打印错误
		logger.Errorf("请求异常 url=[%v] err=[%v]", url, err)
	}
	//错误响应格式处理
	if code != 200 {
		//缓存错误信息
		responseBody.Status = code
		responseBody.Msg = responseStr
	}
	//打印请求参数
	logger.Debugf("接口请求结果 url=[%v] response=[%+v]", url, responseBody)
	//返回响应
	return responseBody
}
func PostHttpBase2(url string, jsonBody map[string]interface{}, header map[string]interface{}) HttpResponse2 {
	//请求响应的结构体
	responseStr, responseBody := "", HttpResponse2{}
	code := 0
	//请求发送逻辑
	err := gout.
		// POST请求
		POST(url).
		// 打开debug模式
		Debug(checkDebug()).
		// 设置http header
		SetHeader(gout.H(header)).
		// SetJSON设置http body为json
		// 同类函数有SetBody, SetYAML, SetXML, SetForm, SetWWWForm
		SetJSON(gout.H(jsonBody)).
		//设置不同的code类型的回调处理
		Callback(func(c *gout.Context) (err error) {
			switch c.Code {
			case 200: //http code为200时，服务端返回的是json 结构
				c.BindJSON(&responseBody)
			default: //http code不为200时，服务端返回是html 字符串
				c.BindBody(&responseStr)
			}
			code = c.Code
			return nil
		}).
		// 结束函数
		Do()
	// 判断错误
	if err != nil {
		//打印错误
		logger.Errorf("请求异常 url=[%v] err=[%v]", url, err)
	}
	//错误响应格式处理
	if code != 200 {
		//缓存错误信息
		responseBody.Status = code
		responseBody.Msg = responseStr
	}
	//打印请求参数
	logger.Debugf("接口请求结果 url=[%v] response=[%+v]", url, responseBody)
	//返回响应
	return responseBody
}

//map参数
func PostHttpResBody(url string, jsonBody map[string]interface{}) string {
	//请求响应的结构体
	responseStr := ""
	//code := 0
	err := gout.
		// POST请求
		POST(url).
		// 打开debug模式
		Debug(checkDebug()).
		// 设置http header
		SetHeader(gout.H(formatHttpHeader())).
		// SetJSON设置http body为json
		// 同类函数有SetBody, SetYAML, SetXML, SetForm, SetWWWForm
		SetJSON(gout.H(jsonBody)).
		//绑定所有的响应类型结果
		BindBody(&responseStr).
		// 结束函数
		Do()
	// 判断错误
	if err != nil {
		//打印错误
		logger.Errorf("请求异常 url=[%v] err=[%v]", url, err)
	}
	//打印请求参数
	logger.Debugf("接口请求结果 url=[%v] response=[%+v]", url, responseStr)
	//返回响应
	return responseStr
}

//map参数
func FormPostHttp(url string, jsonBody map[string]interface{}) HttpResponse {
	//请求响应的结构体
	responseStr, responseBody := "", HttpResponse{}
	code := 0
	//请求发送逻辑
	err := gout.
		// POST请求
		POST(url).
		// 打开debug模式
		Debug(checkDebug()).
		// 设置http header
		SetHeader(gout.H(formatHttpHeader())).
		// SetJSON设置http body为json
		// 同类函数有SetBody, SetYAML, SetXML, SetForm, SetWWWForm
		SetWWWForm(gout.H(jsonBody)).
		//设置不同的code类型的回调处理
		Callback(func(c *gout.Context) (err error) {
			switch c.Code {
			case 200: //http code为200时，服务端返回的是json 结构
				c.BindJSON(&responseBody)
			default: //http code不为200时，服务端返回是html 字符串
				c.BindBody(&responseStr)
			}
			code = c.Code
			return nil
		}).
		// 结束函数
		Do()
	// 判断错误
	if err != nil {
		//打印错误
		logger.Errorf("请求异常 url=[%v] err=[%v]", url, err)
	}
	//错误响应格式处理
	if code != 200 {
		//缓存错误信息
		responseBody.Status = code
		responseBody.Msg = responseStr
	}
	//打印请求参数
	logger.Debugf("接口请求结果 url=[%v] response=[%+v]", url, responseBody)
	//返回响应
	return responseBody
}

//请求头对象
func formatHttpHeader() map[string]interface{} {
	//自定义请求头对象
	header := make(map[string]interface{})
	//通用的自定义请求头参数
	return header
}

//自定义是否开启debug
func checkDebug() gout.DebugOpt {
	//判断是否开启debug
	return gout.DebugFunc(func(o *gout.DebugOption) {
		//判断
		o.Debug = goutDebug
	})
}
